Skip to content

Assorted usability fixes#192

Merged
Corey-Zumar merged 21 commits intoucbrise:developfrom
dcrankshaw:cleanup_clipper_api
Jun 5, 2017
Merged

Assorted usability fixes#192
Corey-Zumar merged 21 commits intoucbrise:developfrom
dcrankshaw:cleanup_clipper_api

Conversation

@dcrankshaw
Copy link
Contributor

@dcrankshaw dcrankshaw commented Jun 2, 2017

This PR makes several backwards-compatible usability fixes to make Clipper less confusing. In particular:

  • Fixes Remove uid from prediction queries until personalization is supported #184: Removes uid from prediction query schema which was very confusing, because the uid must be set to 0 in the current version of Clipper. Now we just set it internally.
  • Fixes Unloading old models #176: Adds a method remove_inactive_containers() to clean up inactive containers (@rmdort)
  • Addresses several of the issues in Confusing parts of Clipper Manager API #188
    • imports the Clipper class in the clipper_admin module, so now users can import Clipper with from clipper_admin import Clipper
    • Makes inspect_selection_policy private so it doesn't show up in API documentation
    • Makes model labels optional and removes them from the examples
  • Adds a check to clipper_admin for python 3 and exits with an error message if Python 3 is detected.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/356/
Test FAILed.

import sys
if sys.version_info >= (3, 0):
sys.stdout.write(
"Sorry, clipper_admin requires Python 2.x, not Python 3.x\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Sorry, clipper_admin requires Python 2.x, but you are running Python 3.x" seems clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


Example
-------
Define a feature function ``center()`` and train a model on the featurized input::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Extra colon after input

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an intentional pydoc markup symbol (https://docs.python.org/devguide/documenting.html#source-code)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for clarifying!

self.add_container(model_name, model_version)

def remove_inactive_containers(self, model_name):
# TODO: Test this function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming this is blocked by #187 and you'd like to merge this PR first. If not, we should use the branch associated with #187 as a base and add a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I want to add a test for this. Let's get #187 merged before this. Leaving the TODO in for now.

@@ -201,7 +199,6 @@
" 2,\n",
" os.path.abspath(\"tf_cifar_model\"),\n",
" \"clipper/tf_cifar_container:latest\",\n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the cifar and sklearn containers reference version 0.1 as opposed to latest as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters for this tutorial.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

for container in container_ids:
# returns a string formatted as "<model_name>:<model_version>"
container_model_name_and_version = self._execute_root(
"docker inspect --format \"{{ index .Config.Labels \\\"%s\\\"}}\" %s"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails in the case where no model containers are actively running.

>>> inst.remove_inactive_containers("m1")

Fatal error: local() encountered an error (return code 1) while executing 'docker inspect --format "{{ index .Config.Labels \"ai.clipper.model_container.model_version\"}}" '

================================ Standard error ================================

"docker inspect" requires at least 1 argument(s).
See 'docker inspect --help'.

Usage:  docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Return low-level information on Docker objects

================================================================================

Aborting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed.

subprocess.call("docker save -o /tmp/{fn}.tar {cn}".format(
fn=saved_fname, cn=container_name))
tar_loc = "/tmp/{fn}.tar".format(fn=saved_fname)
self._execute_put(tar_loc, tar_loc)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tar_loc is now undefined yet is being referenced. Why were these lines removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh weird. They were not supposed to be. Adding them back.

if __name__ == '__main__':
host = "localhost"
clipper = cm.Clipper(host, check_for_docker=False)
clipper = Clipper(host, check_for_docker=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't we check for docker here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this example doesn't start Clipper, it assumes there is already a Clipper instance running and model connected. We don't check for Docker so that the example works even if you aren't using Docker to run Clipper.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it! The key part is the docker-independent functionality.

Copy link
Contributor

@jegonzal jegonzal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Corey-Zumar did an excellent job reviewing. I would approve pending his comments.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/361/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/362/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/364/
Test FAILed.

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/365/
Test PASSed.

Copy link
Contributor

@Corey-Zumar Corey-Zumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Let me know if I should hold off until #187 is merged. If not, we should create an issue reminding us to write a test for remove_inactive_containers.

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/367/
Test PASSed.

@dcrankshaw
Copy link
Contributor Author

@Corey-Zumar this went through a big round of changes, so you'd better review again

container_name,
labels,
input_type,
labels=[DEFAULT_LABEL],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of having all models get a "default" label? Can this be defaulted to []?

# Get all Docker containers tagged as model containers
num_containers_removed = 0
with hide("output", "warnings", "running"):
containers = self._execute_root(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reasoning for dropping into shell commands over using libraries? e.g. https://docker-py.readthedocs.io/en/stable/containers.html#docker.models.containers.ContainerCollection.list

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplicity and wanting to use the same commands locally and remotely. As we refactor clipper_manager.py we should definitely look into the Python SDK.

Copy link
Contributor

@Corey-Zumar Corey-Zumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just requesting that we rename an integration test file + a nit comment. Looks good in general

echo -e "\nRunning integration tests\n\n"
cd $DIR
python ../integration-tests/clipper_manager_tests.py
python ../integration-tests/light_load_all_functionality.py 2 3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have multiple integration tests, let's rename light_load_all_functionality to something more descriptive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

std::string test_json_string =
"{\"uid\": 23, \"input\": \"hello world. This is a test string with "
"{\"input\": \"hello world. This is a test string with "
"punctionation!@#$Y#;}#\"}";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nit: Typo in "punctuation".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a real word anyway. Leaving as is.

cur_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath('%s/../' % cur_dir))
import clipper_manager
from clipper_admin import clipper_manager
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT clipper_manager is only used to access the Clipper class so we could directly import Clipper here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yeah good catch. This is a holdover from before the package structure existed.

sys.path.insert(0, os.path.abspath('%s/../clipper_admin/' % cur_dir))
import clipper_manager as cm
sys.path.insert(0, os.path.abspath('%s/../' % cur_dir))
from clipper_admin import clipper_manager as cm
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto about importing Clipper directly

@dcrankshaw
Copy link
Contributor Author

@Corey-Zumar @feynmanliang addressed your comments. @Corey-Zumar please merge once the tests pass.

Copy link
Contributor

@Corey-Zumar Corey-Zumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/390/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/391/
Test FAILed.

@dcrankshaw
Copy link
Contributor Author

jenkins test this please

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/393/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/394/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/395/
Test FAILed.

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Clipper-PRB/396/
Test PASSed.

@Corey-Zumar Corey-Zumar merged commit fc7e2be into ucbrise:develop Jun 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove uid from prediction queries until personalization is supported Unloading old models

5 participants